package com.smartalarmclock.Model;


import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;

import com.smartalarmclock.Model.Exceptions.DataEntityDoesNotExistException;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

final class Snooze extends ReferencedDataEntity implements ISnooze {

	// Database Constants
	
	public static final String SnoozeTableName = "Snooze";
	
	private static final String c_SnoozeColumnNameDuration = "Duration";
	
	private static final String[] c_QueryAllColumns = new String[] { c_ColumnNameId, c_SnoozeColumnNameDuration };
	
	// Members
	
	private static final int c_DefaultSnoozeDurationInMinutes = 10;
	
	private int m_Duration;
	
	// Constructors
	
	/**
	 * Public Constructor for new instances
	 * @param durationInMinutes the number of minutes between snooze
	 */
	protected Snooze(int durationInMinutes) {
		super();
		m_Duration = durationInMinutes;
	}
	
	/**
	 * Public Constructor for new instances, using the default duration 
	 */
	protected Snooze() {
		this(c_DefaultSnoozeDurationInMinutes);
	}
	
	/**
	 * Private Constructor for instances loaded from the DB.
	 * @param id the existing id of the instance in the DB.
	 * @param durationInMinutes the number of minutes between snoozes
	 */
	private Snooze(int id, int durationInMinutes) {
		super(id);
		m_Duration = durationInMinutes;
	}
	
	// ISnooze implementation
	
	/**
	 * @return the duration between snoozes
	 */
	public int GetDurationInMinutes() {
		return m_Duration;
	}
	
	/**
	 * Sets the duration between snoozes
	 * @param durationInMinutes the number of minutes between snoozes
	 */
	public void SetDurationInMinutes(int durationInMinutes) {
		m_Duration = durationInMinutes;
		SetUpdated();
	}
	
	// Public Methods
	
	/**
	 * @return the CREATE TABLE statement of the Snooze table
	 */
	static String GetSqlStatementCreateSnoozeTable() {
		return "CREATE TABLE " + SnoozeTableName + " (" +
				c_ColumnNameId + 					" INTEGER PRIMARY KEY, " +
				c_SnoozeColumnNameDuration + 		" INTEGER NOT NULL)";
	}
	
	/**
	 * @return the DROP TABLE statement of the Snooze table
	 */
	static String GetSqlStatementDropSnoozeTable() {
		return "DROP TABLE IF EXISTS " + SnoozeTableName;
	}
	
	/**
	 * Queries the DB for the Snooze instance with the given id.
	 * @param context the context of the request (the originating Activity)
	 * @param snoozeId the id of the Snooze instance
	 * @return the matching Snooze instance
	 * @throws DataEntityDoesNotExistException if the Snooze record with the matching id was not found
	 */
	static Snooze GetSnoozeById(Context context, int snoozeId) throws DataEntityDoesNotExistException {
		SQLiteDatabase db = OpenDBForReading(context);
		Cursor cursor = db.query(
			SnoozeTableName,
			c_QueryAllColumns,
			c_ColumnNameId + "=" + snoozeId,
			null, null, null, null);
		
		try {
			if (!cursor.moveToFirst()) {
				throw new DataEntityDoesNotExistException(Snooze.class, c_ColumnNameId + "=" + snoozeId);
			}
			
			return new Snooze(
				snoozeId,
				cursor.getInt(cursor.getColumnIndex(c_SnoozeColumnNameDuration)));
			}
		finally {
			cursor.close();
			db.close();
		}
	}
	
	// DataEntity implementation
	
	@Override
	protected Hashtable<String, ContentValues> GetRecordValues() {
		ContentValues values = new ContentValues();
		values.put(c_SnoozeColumnNameDuration, m_Duration);
		
		Hashtable<String, ContentValues> valuesTable = new Hashtable<String, ContentValues>();
		valuesTable.put(SnoozeTableName, values);
		return valuesTable;
	}

	@Override
	protected Set<String> GetTableNames() {
		HashSet<String> tableNames = new HashSet<String>();
		tableNames.add(SnoozeTableName);
		return tableNames;
	}

	// IDataEntity implementation
	
	@Override
	public void Refresh(Context context) throws DataEntityDoesNotExistException {
		Snooze tempSnooze = GetSnoozeById(context, GetId());
		m_Duration = tempSnooze.GetDurationInMinutes();
	}
}
